home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / MacPNG Library 1.02 / pngMacSrc 1.02 / Re- Mac Port of PNG libraries < prev    next >
Text File  |  1996-05-16  |  16KB  |  430 lines

  1. Mark,
  2.  
  3.         I just surfed to your Web page, not bad at all. (I'm based in
  4. mississauga ont. BTW) With Regards to ReadPNG.c. I basically added my own
  5. CreatePICT2 routine to use a GWorld to convert the raw pixel buffer from
  6. the PNG image returned in row_buf. Unfortunately it isn't working, and i'm
  7. not sure whether the stuff read into row_buf was wrong, or whether my
  8. copying of the pixel image from the PNG buffer to the Gworld buffer is
  9. wrong because I'm not taking into account something about the PNG image
  10. layout. Any suggestions would be appreciated.
  11.  
  12.  
  13.  
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "png.h"
  18.  
  19. // Requires: libpng, zlib, ANSI (4i) C lib's
  20.  
  21. #include <Files.h>
  22. #include <Memory.h>
  23.  
  24. #define         RECT_TOP(rect)                                  (rect).top
  25. #define         RECT_LEFT(rect)                                 (rect).left
  26. #define         RECT_BOTTOM(rect)                               (rect).bottom
  27. #define         RECT_RIGHT(rect)                                (rect).right
  28.  
  29. #define         RECT_WIDTH(rect)                                (RECT_RIGHT(rect) - RECT_LEFT(rect) )
  30. #define         RECT_HEIGHT(rect)                               (RECT_BOTTOM(rect) - RECT_TOP(rect) )
  31. #define         RECT_MIDX(rect)                                 (RECT_LEFT(rect) + (RECT_RIGHT(rect) - RECT_LEFT(rect) >> 1) )
  32. #define         RECT_MIDY(rect)                                 (RECT_TOP(rect) + (RECT_BOTTOM(rect) - RECT_TOP(rect) >> 1) )
  33.  
  34.  
  35. extern  OSErr DumpPixMap(PixMapHandle aPixMap);
  36. PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode);
  37. PicHandle ReadPGN(FSSpec *sfFilePtr);
  38.  
  39.  
  40. PicHandle ReadPGN(FSSpec *sfFilePtr)
  41. {
  42.         OSErr err = noErr;
  43.         short savedVol;
  44.         Str31 name;
  45.  
  46.         png_struct      read_ptr;
  47.         png_info        info_ptr;
  48.         png_info        end_info;
  49.  
  50.         FILE            *fpin;
  51.         png_byte        *row_buf;
  52.         png_uint_32 rowbytes;
  53.         png_uint_32 y, x;
  54.         int             channels, num_pass, pass;
  55.         PicHandle       myPic =  nil;
  56.  
  57.         BlockMoveData((Ptr)(sfFilePtr->name), (Ptr)name, sizeof(Str31));
  58.  
  59.         err = GetVol(0, &savedVol);
  60.         if (err == noErr)
  61.                 {
  62.                         err = HSetVol(0, sfFilePtr->vRefNum, sfFilePtr->parID);
  63.                         if (err == noErr)
  64.                         {
  65.                                 p2cstr(name);
  66.  
  67.                                 row_buf = (png_byte *)0;
  68.  
  69.                                 fpin = fopen((char *) name, "rb");
  70.                                 if (!fpin)
  71.                                 {
  72.                                         //      fprintf(STDERR, "Could not find input file %s\n", inname);
  73.                                         return NULL;
  74.                                 }
  75.  
  76.                                 if (setjmp(read_ptr.jmpbuf))
  77.                                 {
  78.                                         //      fprintf(STDERR, "libpng read error\n");
  79.                                         fclose(fpin);
  80.                                         return NULL;
  81.                                 }
  82.  
  83.                                 png_read_init(&read_ptr);
  84.                                 png_info_init(&info_ptr);
  85.                                 png_info_init(&end_info);
  86.  
  87.                                 png_init_io(&read_ptr, fpin);
  88.                                 png_read_info(&read_ptr, &info_ptr);
  89.  
  90.                         #if OutputInfo  /* RMF */
  91.                                 fprintf(STDERR, "%s, Width = %d, Height = %d, Depth = %d\n",
  92.                                         inname, info_ptr.width, info_ptr.height, info_ptr.bit_depth);
  93.                                 fprintf(STDERR, "Color type = %d, interlace_type = %d\n",
  94.                                         info_ptr.color_type, info_ptr.interlace_type);
  95.                         #endif
  96.  
  97.                                 if ((info_ptr.color_type & 3) == PNG_COLOR_MASK_COLOR)
  98.                                                 channels = 3;
  99.                                 else    channels = 1;
  100.  
  101.                                 if (info_ptr.color_type & PNG_COLOR_MASK_ALPHA)
  102.                                         channels++;
  103.  
  104.                                 rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
  105. //                              row_buf = (png_byte *)malloc((size_t)rowbytes);
  106.                                 row_buf = (png_byte *)NewPtrClear(rowbytes);
  107.  
  108.                                 if (!row_buf)
  109.                                 {
  110. //R4L                                   fprintf(STDERR, "no memory to allocate row buffer\n");
  111.                                         png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
  112.                                         fclose(fpin);
  113.                                         return NULL;
  114.                                 }
  115.  
  116.                                 if (info_ptr.interlace_type)
  117.                                 {
  118.                                         num_pass = png_set_interlace_handling(&read_ptr);
  119.                                 }
  120.                                 else
  121.                                 {
  122.                                         num_pass = 1;
  123.                                 }
  124.  
  125.  
  126.                                 for (pass = 0; pass < num_pass; pass++)
  127.                                 {
  128.                                         for (y = 0; y < info_ptr.height; y++)
  129.                                         {
  130.                                                 png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1);  // Read one row of image data
  131.                                         }
  132.                                 }
  133.  
  134.                                 png_read_end(&read_ptr, &end_info);
  135.  
  136.                 x = info_ptr.width;
  137.                 y = info_ptr.height;
  138.  
  139.                 if (info_ptr.bit_depth == 24)
  140.                 {
  141.                         rowbytes = (x * 4L); // Make Multiple of 4 bytes (32bit RGB image)
  142.                 }
  143.                 else
  144.                 {
  145.  
  146.         //RS?           ByteScanLine = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L);          /* Make Multiple of byte */
  147.                         rowbytes = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L);              /* Make Multiple of byte */
  148.                 }
  149.  
  150.         // info_ptr.color_type =
  151.         // PNG_COLOR_TYPE_PALETTE
  152.         // PNG_COLOR_TYPE_RGB
  153.         // PNG_COLOR_TYPE_GRAY
  154.         // PNG_COLOR_TYPE_RGB_ALPHA
  155.         // PNG_COLOR_TYPE_GRAY_ALPHA
  156.  
  157.         // Black & White Image
  158.  
  159.                 if (info_ptr.bit_depth == 1)
  160.                 {
  161.                         BitMap  theBits;
  162.  
  163.                         theBits.baseAddr = (Ptr) row_buf; // Set up new BitMap
  164.                         theBits.rowBytes = rowbytes;                    // width of image
  165.                         SetRect(&(theBits.bounds),      0, 0, x, y);
  166.  
  167.         //R4L           myPic = MakePictFromBW(&theBits);
  168. // create a PicHandle from B&W BitMap
  169.  
  170.  
  171. // Cleanup and Exit.
  172.                 }
  173.                 else
  174.                 {
  175.  
  176.                         CTabHandle      macCtabHandle = nil;// Color Table for 2, 4, 8 bit images
  177.                         PixMap  srcBits;
  178.  
  179.  
  180.                         if (info_ptr.bit_depth >= 2 && info_ptr.bit_depth <= 8)
  181.                         {
  182.                                         if (info_ptr.valid & PNG_INFO_PLTE)
  183.                                         {
  184.                                                 info_ptr.palette;
  185.                                                 info_ptr.num_palette;
  186.                                                 macCtabHandle = nil;    // Get the color table...
  187.                                         }
  188.                         }
  189.         // See: QuickDraw.h
  190.         // Setup PixMap data structure:
  191.                 srcBits.baseAddr = (char *)row_buf;
  192. // ptr to the Pixcell data
  193.  
  194. // offset to next scan line
  195.                 srcBits.rowBytes = rowbytes | 0x8000;                   // pixmap (4, 8, 16 or 24/32bit image)
  196.  
  197.                 srcBits.bounds.top = 0; // encloses bitmap
  198.                 srcBits.bounds.left = 0;
  199.                 srcBits.bounds.bottom = y;
  200.                 srcBits.bounds.right = x;
  201.                 srcBits.pmVersion = 0; // pixMap version number
  202.  
  203.                 srcBits.packType = 1; // defines packing format: 1 = direct
  204.  
  205.                 srcBits.packSize = 0L; // length of pixel data
  206.                 srcBits.hRes = 0x480000; // 72dpi fixed point
  207.                 srcBits.vRes = 0x480000; // vert. resolution (ppi)
  208.                 srcBits.planeBytes = 0L; // offset to next plane
  209.  
  210.                 srcBits.pmTable = macCtabHandle; // color map for this pixMap
  211.                 srcBits.pmReserved = 0;
  212.  
  213.                         if (info_ptr.bit_depth == 24)
  214.                         { // RGB data 24bit color, no Color Table
  215.                                 srcBits.pixelType = RGBDirect;
  216.                                 srcBits.pixelSize = 32; // # bits in pixel
  217.                                 srcBits.cmpCount = 3; // # components in pixel (R,G,B)
  218.                                 srcBits.cmpSize = 8; // # bits per component (3 * 8) = 
  219.                                                      //   24bits + 8bits pad = 32 bits
  220.  
  221.                         }
  222.                         else
  223.                         {
  224.  
  225.  
  226.                                 // Else: 4bit or 8bit color image
  227.                                 srcBits.pixelType = 0;
  228.                                 srcBits.pixelSize = info_ptr.bit_depth; // # bits in pixel
  229.                                 srcBits.cmpCount = 1;                    // # components in pixel
  230.                                 srcBits.cmpSize = info_ptr.bit_depth;    // # bits per component
  231.                         }
  232.  
  233.  
  234.                         myPic = CreatePICT2( &srcBits, &srcBits.bounds,ditherCopy);
  235.  
  236.                         if (srcBits.pmTable)
  237.                                 DisposHandle((Handle) srcBits.pmTable); // Free Color table allocated
  238.  
  239.  
  240.                 }
  241.                 /*------------ */
  242.  
  243.    /* clean up after the read, and free any memory allocated */
  244.                 png_read_destroy(&read_ptr, &info_ptr, &end_info);
  245.  
  246.    /* free the structures */
  247.                 free(row_buf);
  248.  
  249.                 fclose(fpin);
  250.                 SetVol(0, savedVol);
  251.                 return myPic;
  252.         }       // End readPNG()
  253.  
  254. }
  255.         return NULL;
  256. }
  257.  
  258.  
  259. PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode)
  260. {
  261.         OSErr err;
  262.         GWorldPtr               imageGWorld = NULL;
  263.         PixMapHandle    phPixMap;
  264.         Ptr                             imageBaseAddr,imagePtr;
  265.         long                    bytesPerRow,gworldBytesPerRow;
  266.         CGrafPtr                savePort;
  267.         GDHandle                saveDevice;
  268.         short                   line,imageHeight;
  269.  
  270.         GetGWorld(&savePort, &saveDevice);
  271.  
  272.         err =
  273. NewGWorld(&imageGWorld,pixMap->pixelSize,boundsRect,pixMap->pmTable,NULL,0L)
  274. ;
  275.  
  276.         if (err)
  277.                 return NULL;
  278.  
  279.         SetGWorld(imageGWorld, NULL);
  280.  
  281.         phPixMap          = GetGWorldPixMap(imageGWorld);
  282.         LockPixels(phPixMap);
  283.         imageBaseAddr = GetPixBaseAddr(phPixMap);
  284.  
  285.         bytesPerRow = pixMap->rowBytes & 0x3fff;
  286. //Bytes per Row
  287.         gworldBytesPerRow = (**phPixMap).rowBytes & 0x3fff;
  288.  
  289.         imagePtr = pixMap->baseAddr;
  290.         imageHeight = boundsRect->bottom - boundsRect->top;
  291.  
  292.         for (line = boundsRect->top; line < boundsRect->bottom;line++)
  293.         {
  294.                 BlockMove(imagePtr,imageBaseAddr,bytesPerRow);
  295.                 imageBaseAddr = imageBaseAddr + gworldBytesPerRow;
  296.                 imagePtr = imagePtr + bytesPerRow;
  297.         }
  298.  
  299.         SetGWorld(savePort, saveDevice);
  300.         err = DumpPixMap(phPixMap);             //Debug Purposes just
  301. output the pixmap to a window the size of the pixmap
  302.         UnlockPixels(phPixMap);
  303.         DisposeGWorld(imageGWorld);
  304.  
  305.         return (PicHandle)NULL;
  306. }
  307.  
  308.  
  309. OSErr DumpPixMap(PixMapHandle aPixMap)
  310. {
  311.         WindowPtr       myWind;
  312.         Rect            windowRect,pixRect;
  313.         long            finalTick;
  314.  
  315.  
  316.         RGBColor        white = {0xFFFF,0xFFFF,0xFFFF};
  317.         RGBColor        black = {0x0000,0x0000,0x0000};
  318.  
  319.         if (aPixMap == NULL)
  320.         {
  321.                 DebugStr("\pNull Pixmap Handle in DumpPixMap");
  322.                 return memFullErr;
  323.         }
  324.  
  325.         HLock((Handle)aPixMap);
  326.         pixRect = (**aPixMap).bounds;
  327.  
  328.         centerRectOnMainScreen(&pixRect,&pixRect);
  329.         InsetRect(&pixRect,2,2);
  330.  
  331.         myWind = NewWindow(NULL, &pixRect, "\p Pixmap", TRUE, documentProc,
  332. (WindowPtr)-1, FALSE, NULL);
  333.  
  334.         if (myWind != nil)
  335.         {
  336.                 ShowWindow(myWind);
  337.         }
  338.  
  339.         SelectWindow(myWind);           // activate the "Shell Window"
  340.         windowRect = myWind->portRect;
  341.         InsetRect(&windowRect,1,1);
  342.  
  343.         RGBForeColor(&black);
  344.         RGBBackColor(&white);
  345.  
  346.  
  347.         CopyBits(*(BitMap **)aPixMap,
  348.                         &(myWind)->portBits,
  349.                         &windowRect,
  350.                         &windowRect,
  351.                         srcCopy, NULL);
  352.  
  353.         BeginUpdate(myWind);
  354.         EndUpdate(myWind);
  355.  
  356.         Delay(60,&finalTick);
  357.         Debugger();
  358.         DisposeWindow(myWind);
  359.  
  360.         HUnlock((Handle)aPixMap);
  361.  
  362.         return noErr;
  363.  
  364. }
  365.  
  366. void centerRectOnMainScreen(Rect *theRect,Rect *resultRect)
  367. {
  368.         short var1,var2;
  369.         Rect  centerRect;
  370.         GDHandle mainDevice;
  371.  
  372.         mainDevice = GetMainDevice();
  373.         centerRect = (**mainDevice).gdRect;
  374.  
  375.         *resultRect = *theRect;
  376.  
  377.         var1 = theRect->right - theRect->left;
  378.         var2 = centerRect.right - centerRect.left;
  379.  
  380.         if (var1 < var2)
  381.         {
  382.                 RECT_LEFT(*resultRect) = RECT_MIDX(centerRect) - (var1 >> 1);
  383.                 RECT_RIGHT(*resultRect) = RECT_LEFT(*resultRect) + var1;
  384.         }
  385.  
  386.         var1 = theRect->bottom - theRect->top;
  387.         var2 = centerRect.bottom - centerRect.top;
  388.  
  389.         if (var1 < var2)
  390.         {
  391.                 RECT_TOP(*resultRect) = RECT_MIDY(centerRect) - (var1 >> 1);
  392.                 RECT_BOTTOM(*resultRect) = RECT_TOP(*resultRect) + var1;
  393.         }
  394.  
  395. }
  396.  
  397. ,
  398. >
  399. >sorry for the problems .. I did start to write ReadPNG.c (and never got
  400. >back to it), I did think I have included it in the archive file...
  401. >
  402. >I was planning on finishing it and getting it to work for my external
  403. >translators (XTND, MacEasy Open, etc...).
  404. >
  405. >I don't know when I will have time to finish it.  What problems have you
  406. >fixed and what problems are you having?
  407. >
  408. >If my memory is correct, I was going to manually create an offscreen pixmap
  409. >and color table and then call a special routine for creating PICT handles
  410. >that is portable and does not require color quickdraw (you could used
  411. >OpenPicture()... etc).
  412. >
  413. >currently no update ... but when I do get to it will send you a note. Let
  414. >me know If you get it working, and I will include it as an update.
  415. >
  416. >
  417. >>        I'm trying to get a simple demo up and running that reads and
  418. >>displays a PNG image using your mac CW port. I tried compiling the ReadPNG
  419. >>file, but there are a host of problems. I've tried to fix the obvious ones,
  420. >>but am having problems getting the image to display properly. Did you write
  421. >>ReadPNG.c? Is there an updated version?
  422. >>
  423. >>Roger Smith
  424. >
  425. ><<<<->>>>|
  426. > Mark Fleming, http://ccsmacinfo.ccs.queensu.ca/Mark/
  427. > Stauffer Library, Room 011c, Computing & Comm. Services,
  428. > Queen's University at Kingston, Ontario, Canada, K7L 3N6
  429. > MarkF@post.QueensU.CA, Tel:1-613-545-2039 Fax:613-545-6798
  430.